package com.blog.cmrpersonalblog.controller;

import cn.dev33.satoken.stp.StpUtil;
import com.blog.cmrpersonalblog.annotation.RateLimit;
import com.blog.cmrpersonalblog.common.Result;
import com.blog.cmrpersonalblog.dto.article.response.UserArticleDetailResponse;
import com.blog.cmrpersonalblog.dto.article.request.UserArticleCreateRequest;
import com.blog.cmrpersonalblog.dto.user.request.UserArticleUpdateRequest;
import com.blog.cmrpersonalblog.dto.article.response.UserArticleResponse;
import com.blog.cmrpersonalblog.dto.user.response.UserInteractionStatus;
import com.blog.cmrpersonalblog.enums.LimitType;
import com.blog.cmrpersonalblog.service.UserArticleService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.Valid;
import java.util.List;

/**
 * 用户端文章控制器
 * 提供面向普通用户的文章查看、交互功能
 */
@Slf4j
@RestController
@RequestMapping("/api/articles")
@CrossOrigin(origins = "*", maxAge = 3600)
public class UserArticleController {

   @Resource
    private UserArticleService userArticleService;

    /**
     * 获取文章详情
     * 
     * @param articleId 文章ID
     * @return 文章详情
     */
    @GetMapping("/{articleId}")
    public Result<UserArticleDetailResponse> getArticleDetail(
            @PathVariable @NotNull Long articleId) {
        
        log.info("用户查看文章详情: articleId={}", articleId);
        
        try {
            // 获取当前用户ID（如果已登录）
            Long userId = null;
            try {
                if (StpUtil.isLogin()) {
                    userId = StpUtil.getLoginIdAsLong();
                }
            } catch (Exception e) {
                // 未登录状态，继续执行
                log.debug("用户未登录，以游客身份查看文章");
            }

            // 获取文章详情（默认更新浏览量）
            UserArticleDetailResponse article = userArticleService.getArticleDetail(articleId, userId, true);
            
            return Result.success("获取文章详情成功", article);
            
        } catch (Exception e) {
            log.error("获取文章详情失败: articleId={}", articleId, e);
            return Result.error("获取文章详情失败：" + e.getMessage());
        }
    }

    /**
     * 获取文章详情（不更新浏览量）
     * 用于预览、编辑等场景
     * 
     * @param articleId 文章ID
     * @return 文章详情
     */
    @GetMapping("/{articleId}/preview")
    public Result<UserArticleDetailResponse> getArticlePreview(@PathVariable @NotNull Long articleId) {
        log.info("预览文章详情: articleId={}", articleId);
        
        try {
            // 获取当前用户ID（如果已登录）
            Long userId = null;
            try {
                if (StpUtil.isLogin()) {
                    userId = StpUtil.getLoginIdAsLong();
                }
            } catch (Exception e) {
                // 未登录状态，继续执行
            }

            // 获取文章详情（不更新浏览量）
            UserArticleDetailResponse article = userArticleService.getArticleDetail(articleId, userId, false);
            
            return Result.success("获取文章预览成功", article);
            
        } catch (Exception e) {
            log.error("获取文章预览失败: articleId={}", articleId, e);
            return Result.error("获取文章预览失败：" + e.getMessage());
        }
    }

    /**
     * 文章点赞/取消点赞
     * 
     * @param articleId 文章ID
     * @param isLike 是否点赞（true-点赞，false-取消点赞）
     * @return 操作结果
     */
    @PostMapping("/{articleId}/like")
    public Result<String> toggleLike(
            @PathVariable @NotNull Long articleId,
            @RequestParam boolean isLike) {
        
        // 检查登录状态
        if (!StpUtil.isLogin()) {
            return Result.unauthorized("请先登录");
        }
        
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("用户切换文章点赞状态: userId={}, articleId={}, isLike={}", userId, articleId, isLike);
        
        try {
            boolean success = userArticleService.toggleArticleLike(articleId, userId, isLike);
            
            if (success) {
                String message = isLike ? "点赞成功" : "取消点赞成功";
                return Result.success(message);
            } else {
                String message = isLike ? "点赞失败" : "取消点赞失败";
                return Result.error(message);
            }
            
        } catch (Exception e) {
            log.error("切换文章点赞状态失败: userId={}, articleId={}", userId, articleId, e);
            return Result.error("操作失败：" + e.getMessage());
        }
    }

    /**
     * 文章收藏/取消收藏
     * 
     * @param articleId 文章ID
     * @param isCollect 是否收藏（true-收藏，false-取消收藏）
     * @return 操作结果
     */
    @PostMapping("/{articleId}/collect")
    public Result<String> toggleCollect(
            @PathVariable @NotNull Long articleId,
            @RequestParam boolean isCollect) {
        
        // 检查登录状态
        if (!StpUtil.isLogin()) {
            return Result.unauthorized("请先登录");
        }
        
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("用户切换文章收藏状态: userId={}, articleId={}, isCollect={}", userId, articleId, isCollect);
        
        try {
            boolean success = userArticleService.toggleArticleCollect(articleId, userId, isCollect);
            
            if (success) {
                String message = isCollect ? "收藏成功" : "取消收藏成功";
                return Result.success(message);
            } else {
                String message = isCollect ? "收藏失败" : "取消收藏失败";
                return Result.error(message);
            }
            
        } catch (Exception e) {
            log.error("切换文章收藏状态失败: userId={}, articleId={}", userId, articleId, e);
            return Result.error("操作失败：" + e.getMessage());
        }
    }

    /**
     * 获取相关文章推荐
     * 
     * @param articleId 当前文章ID
     * @param limit 推荐数量（默认5个）
     * @return 相关文章列表
     */
    @GetMapping("/{articleId}/related")
    public Result<List<UserArticleDetailResponse.RelatedArticleInfo>> getRelatedArticles(
            @PathVariable @NotNull Long articleId,
            @RequestParam(defaultValue = "5") Integer limit) {
        
        log.info("获取相关文章推荐: articleId={}, limit={}", articleId, limit);
        
        try {
            List<UserArticleDetailResponse.RelatedArticleInfo> relatedArticles = 
                userArticleService.getRelatedArticles(articleId, limit);
            
            return Result.success("获取相关文章成功", relatedArticles);
            
        } catch (Exception e) {
            log.error("获取相关文章失败: articleId={}", articleId, e);
            return Result.error("获取相关文章失败：" + e.getMessage());
        }
    }

    /**
     * 获取用户对文章的交互状态
     * 
     * @param articleId 文章ID
     * @return 交互状态（点赞、收藏、关注作者等）
     */
    @GetMapping("/{articleId}/interaction-status")
    public Result<UserInteractionStatus> getUserInteractionStatus(
            @PathVariable @NotNull Long articleId) {
        
        // 检查登录状态
        if (!StpUtil.isLogin()) {
            return Result.success("获取交互状态成功", 
                new UserInteractionStatus(false, false, false));
        }
        
        Long userId = StpUtil.getLoginIdAsLong();
        log.debug("获取用户交互状态: userId={}, articleId={}", userId, articleId);
        
        try {
            UserInteractionStatus status = 
                userArticleService.getUserInteractionStatus(articleId, userId);
            
            return Result.success("获取交互状态成功", status);
            
        } catch (Exception e) {
            log.error("获取用户交互状态失败: userId={}, articleId={}", userId, articleId, e);
            return Result.error("获取交互状态失败：" + e.getMessage());
        }
    }

    /**
     * 手动增加文章浏览量
     * 用于特殊场景，如从外部链接访问时
     * 
     * @param articleId 文章ID
     * @param request HTTP请求对象
     * @return 操作结果
     */
    @PostMapping("/{articleId}/view")
    public Result<Void> incrementViewCount(
            @PathVariable @NotNull Long articleId,
            HttpServletRequest request) {
        
        log.debug("手动增加文章浏览量: articleId={}", articleId);
        
        try {
            // 获取用户ID（如果已登录）
            Long userId = null;
            try {
                if (StpUtil.isLogin()) {
                    userId = StpUtil.getLoginIdAsLong();
                }
            } catch (Exception e) {
                // 未登录状态
            }

            // 获取IP地址和用户代理
            String ipAddress = getClientIpAddress(request);
            String userAgent = request.getHeader("User-Agent");

            userArticleService.incrementViewCount(articleId, userId, ipAddress, userAgent);
            
            return Result.success("浏览量更新成功");
            
        } catch (Exception e) {
            log.error("增加文章浏览量失败: articleId={}", articleId, e);
            return Result.error("浏览量更新失败：" + e.getMessage());
        }
    }

    /**
     * 创建文章
     *
     * @param request 文章创建请求
     * @return 创建结果
     */
    @PostMapping
    @RateLimit(count = 5, time = 3600, limitType = LimitType.USER, message = "发布文章过于频繁，请1小时后再试")
    public Result<UserArticleResponse> createArticle(@RequestBody @Valid UserArticleCreateRequest request) {
        // 检查登录状态
        if (!StpUtil.isLogin()) {
            return Result.unauthorized("请先登录");
        }
        
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("用户创建文章: userId={}, title={}", userId, request.getTitle());
        
        try {
            UserArticleResponse article = userArticleService.createArticle(request, userId);
            
            String message = request.getPublishNow() ? "文章发布成功" : "文章保存为草稿";
            return Result.success(message, article);
            
        } catch (Exception e) {
            log.error("创建文章失败: userId={}, title={}", userId, request.getTitle(), e);
            return Result.error("创建文章失败：" + e.getMessage());
        }
    }

    /**
     * 更新文章
     * 
     * @param request 文章更新请求
     * @return 更新结果
     */
    @PutMapping
    public Result<UserArticleResponse> updateArticle(@RequestBody @Valid UserArticleUpdateRequest request) {
        // 检查登录状态
        if (!StpUtil.isLogin()) {
            return Result.unauthorized("请先登录");
        }
        
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("用户更新文章: userId={}, articleId={}", userId, request.getId());
        
        try {
            UserArticleResponse article = userArticleService.updateArticle(request, userId);
            
            String message = request.getPublishNow() ? "文章更新并发布成功" : "文章更新成功";
            return Result.success(message, article);
            
        } catch (Exception e) {
            log.error("更新文章失败: userId={}, articleId={}", userId, request.getId(), e);
            return Result.error("更新文章失败：" + e.getMessage());
        }
    }

    /**
     * 删除文章
     * 
     * @param articleId 文章ID
     * @return 删除结果
     */
    @DeleteMapping("/{articleId}")
    public Result<String> deleteArticle(@PathVariable @NotNull Long articleId) {
        // 检查登录状态
        if (!StpUtil.isLogin()) {
            return Result.unauthorized("请先登录");
        }
        
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("用户删除文章: userId={}, articleId={}", userId, articleId);
        
        try {
            boolean success = userArticleService.deleteArticle(articleId, userId);
            
            if (success) {
                return Result.success("文章删除成功");
            } else {
                return Result.error("文章删除失败");
            }
            
        } catch (Exception e) {
            log.error("删除文章失败: userId={}, articleId={}", userId, articleId, e);
            return Result.error("删除文章失败：" + e.getMessage());
        }
    }

    /**
     * 获取用户的文章列表
     * 
     * @param status 文章状态（可选）
     * @param current 当前页
     * @param size 每页大小
     * @return 文章列表
     */
    @GetMapping("/my")
    public Result<List<UserArticleResponse>> getMyArticles(
            @RequestParam(required = false) Integer status,
            @RequestParam(defaultValue = "1") Long current,
            @RequestParam(defaultValue = "10") Long size) {
        
        // 检查登录状态
        if (!StpUtil.isLogin()) {
            return Result.unauthorized("请先登录");
        }
        
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("获取用户文章列表: userId={}, status={}, current={}, size={}", userId, status, current, size);
        
        try {
            List<UserArticleResponse> articles = userArticleService.getUserArticles(userId, status, current, size);
            return Result.success("获取文章列表成功", articles);
            
        } catch (Exception e) {
            log.error("获取用户文章列表失败: userId={}", userId, e);
            return Result.error("获取文章列表失败：" + e.getMessage());
        }
    }

    /**
     * 发布草稿文章
     * 
     * @param articleId 文章ID
     * @return 发布结果
     */
    @PostMapping("/{articleId}/publish")
    public Result<String> publishDraft(@PathVariable @NotNull Long articleId) {
        // 检查登录状态
        if (!StpUtil.isLogin()) {
            return Result.unauthorized("请先登录");
        }
        
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("发布草稿文章: userId={}, articleId={}", userId, articleId);
        
        try {
            boolean success = userArticleService.publishDraft(articleId, userId);
            
            if (success) {
                return Result.success("文章发布成功");
            } else {
                return Result.error("文章发布失败");
            }
            
        } catch (Exception e) {
            log.error("发布草稿失败: userId={}, articleId={}", userId, articleId, e);
            return Result.error("发布草稿失败：" + e.getMessage());
        }
    }

    /**
     * 下架已发布的文章
     * 
     * @param articleId 文章ID
     * @return 下架结果
     */
    @PostMapping("/{articleId}/withdraw")
    public Result<String> withdrawArticle(@PathVariable @NotNull Long articleId) {
        // 检查登录状态
        if (!StpUtil.isLogin()) {
            return Result.unauthorized("请先登录");
        }
        
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("用户下架文章: userId={}, articleId={}", userId, articleId);
        
        try {
            boolean success = userArticleService.withdrawArticle(articleId, userId);
            
            if (success) {
                return Result.success("文章下架成功");
            } else {
                return Result.error("文章下架失败");
            }
            
        } catch (Exception e) {
            log.error("文章下架失败: userId={}, articleId={}", userId, articleId, e);
            return Result.error("文章下架失败：" + e.getMessage());
        }
    }

    /**
     * 获取客户端IP地址
     */
    private String getClientIpAddress(HttpServletRequest request) {
        String ipAddress = request.getHeader("X-Forwarded-For");
        if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
        }
        return ipAddress;
    }
}
